home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / utilsys / rss14gmd.lha / RSys_1.4gmd / C / rsys.c < prev    next >
C/C++ Source or Header  |  1996-05-05  |  23KB  |  992 lines

  1. /*
  2.    ***************************************************************************
  3.    *
  4.    * Datei:
  5.    *      RSys.c
  6.    *
  7.    * Inhalt:
  8.    *
  9.    *      --- Globale Routinen ---
  10.    *
  11.    *    void About ( void );
  12.    *    void HandleMainPort ( void );
  13.    *    void main ( int argc , char **argv );
  14.    *
  15.    *      --- Lokale  Routinen ---
  16.    *
  17.    *    static int HandleArguments ( char **str );
  18.    *    static int position ( int ch );
  19.    *    static void HandleGadgets ( GADGET *gad );
  20.    *    static void HandleIDPort ( void );
  21.    *    static void HandleMenu ( ULONG code );
  22.    *    static void HandleRawKeys ( ULONG code , ULONG qualifier );
  23.    *    static void HandleVanillaKeys ( ULONG code , ULONG qualifier );
  24.    *    static void Jump ( void );
  25.    *    static void SelectGadget ( GADGET *Gadget );
  26.    *    static void SetMainLVTop ( int top );
  27.    *    static void UnSelectGadget ( GADGET *Gadget );
  28.    *
  29.    * Bemerkungen:
  30.    *      Hauptprogramm und Handling-Routinen von RSys.
  31.    *
  32.    * Erstellungsdatum:
  33.    *      07-Jan-93     Rolf Böhme
  34.    *
  35.    * Änderungen:
  36.    *      07-Jan-93     Rolf Böhme        Erstellung
  37.    *
  38.    ***************************************************************************
  39.  */
  40.  
  41. #include "RSys.h"
  42. #include "protos.h"
  43.  
  44.  
  45. /*#define BETA 1 */
  46.  
  47.  /*
  48.   * Der Kennstring, der von dem DOS-Befehl Version
  49.   * gefunden wird
  50.   */
  51. char *gmdv = "\0$VER: " NAME " " VERSION " (" DATE " " TIME ") " COPYRIGHT " \n";
  52.  
  53.  /*
  54.   * Die Prozedur About() gibt eine Kurzinformation zum
  55.   * Programm RSys aus
  56.   */
  57. void
  58. About (void)
  59. {
  60.   UBYTE info[] =
  61.   "\n»»»»»»»»»»»» " NAME " " VERSION " ««««««««««««\n\n "
  62.   "    The Program was written by\n\n"
  63.   "            Rolf Böhme\n"
  64.   "           Stammestr. 48\n"
  65.   "         30459 Hannover 91\n"
  66.   "              Germany\n"
  67.   "     Z-NET: R.BOEHME@COPS.ZER\n"
  68.   "  FIDO: 2:241/37.2 (Rolf Boehme)\n\n"
  69.   "   It's placed in Public Domain\n"
  70.   "   under the terms of Giftware!\n"
  71.   "Please send small donations, gifts\n"
  72.   " or other little sweeties to me!!\n"
  73.   " \n"
  74.   " Ported to SAS/C by :-\n"
  75.   "       gduncan@werple.net.au \n";
  76.  
  77.   DPOS;
  78.  
  79.   HandleHelp (MN_About);
  80.  
  81.   MyEasyRequest (SysWnd, (UBYTE *) NAME " Info (" DATE ", " TIME ")",
  82.          (UBYTE *) "Continue", info);
  83.   return;
  84. }
  85.  
  86.  /*
  87.   * Die Prozedur Jump() sucht den nächsten
  88.   * PublicScreen in der Systemliste, holt ihn nach
  89.   * vorn und öffnet auf ihm das RSys-Hauptfenster
  90.   */
  91. static void
  92. Jump (void)
  93. {
  94.   SCREEN *NewScr = NULL;
  95.   LIST *PSList = NULL;
  96.   NODE *Node = NULL;
  97.   char savenamebuffer[MAXPUBSCREENNAME + 1];
  98.   int openit;
  99.  
  100.   strcpy (savenamebuffer, (char *) namebuffer);
  101.   /*
  102.    * Sperren der Systemliste aller PubScreens
  103.    */
  104.   PSList = LockPubScreenList ();
  105.  
  106.   /*
  107.    * Aktuellen Knoten finden, also den Screen auf dem sich
  108.    * RSys im Moment befindet
  109.    */
  110.   Forbid ();
  111.   Node = FindName (PSList, namebuffer);
  112.   Permit ();
  113.  
  114.   if (NOT (Node))
  115.     {
  116.       UnlockPubScreenList ();
  117.       ErrorHandle ((char *) namebuffer, SCREEN_ERR, FIND_FAIL, NO_KILL);
  118.     }
  119.   else
  120.     {
  121.       while (Node)
  122.     {
  123.       /*
  124.          * Falls der gefundene PubScreen der letzte im System ist,
  125.          * wird dieser gelocked
  126.        */
  127.       if (NOT (Node->ln_Succ))
  128.         {
  129.           Node = PSList->lh_Head;
  130.           strcpy ((char *) namebuffer, Node->ln_Name);
  131.           NewScr = LockPubScreen (namebuffer);
  132.  
  133.           break;
  134.         }
  135.       else if (NewScr = LockPubScreen ((UBYTE *) Node->ln_Succ->ln_Name))
  136.         {
  137.           strcpy ((char *) namebuffer, Node->ln_Succ->ln_Name);
  138.           break;
  139.         }
  140.  
  141.       /*
  142.          * Falls der Nachfolger-PubScreen nicht gesperrt werden konnte,
  143.          * wird der nächste gesucht.
  144.        */
  145.       Node = Node->ln_Succ;
  146.     }
  147.  
  148.       UnlockPubScreen (NULL, NewScr);
  149.  
  150.       UnlockPubScreenList ();
  151.  
  152.       if (NewScr != lastpubscreen)
  153.     {
  154.       ScreenToFront (NewScr);
  155.  
  156.       CloseASysWindow (&SysWnd, &SysGList, &SysMenus);
  157.       CloseDownScreen ();
  158.  
  159.       OpenMainWindow ();
  160.       RefreshList (LastID);
  161.  
  162.       openit = CloseHelpOnScreen ();
  163.       OpenHelpOnScreen (openit);
  164.  
  165.       ClearIntuiMsgPort (SysWnd);
  166.     }
  167.       else
  168.     {
  169.       strcpy ((char *) namebuffer, savenamebuffer);
  170.       ErrorHandle ("No more Public Screens", SCREEN_ERR, FIND_FAIL, NO_KILL);
  171.     }
  172.     }
  173.  
  174.   return;
  175. }
  176.  
  177.  /*
  178.   * Die Funktion position() gibt für die
  179.   * Gadget-Tastatturabfrage die Position des Zeichens
  180.   * ch in der Zeichenkette itemcode[] zurück
  181.   */
  182. static int
  183. position (int ch)
  184. {
  185.   char *itemcode = "TLMPVAFRIWSHYD J";
  186.  
  187.   /*
  188.    * Die Position des Zeichens errechnet sich aus der
  189.    * Differenz der Zeiger auf das gefundene Zeichen und
  190.    * dem auf die Zeichenkette itemcode
  191.    */
  192.   int pos = (int) (strchr (itemcode, (int) ToUpper ((ULONG) ch)) - itemcode);
  193.  
  194.   return ((pos < 0) ? ~0 : pos);
  195. }
  196.  
  197.  /*
  198.   * In diesem Feld stehen nach dem Aufruf die
  199.   * erwarteten Parameter. Im Falle der verwendeten
  200.   * Schalter steht im entsprechenden Feld opts[i] ein
  201.   * TRUE oder FALSE, jenachdem, ob der Schalter beim
  202.   * Aufruf angegeben wurde oder nicht
  203.   */
  204. LONG opts[COUNT_FLAGS];
  205.  
  206.  /*
  207.   * Diese Funktion parst die Kommandozeile und gibt
  208.   * die Nummer des entsprechenden Schalters zurück.
  209.   * Defaultmäßig wird 12 (Systeminfo) zurückgegeben
  210.   */
  211.  
  212. static int
  213. HandleArguments (char **str)
  214. {
  215.   int ret = 12, j;
  216.   RDARGS *argsptr;
  217.  
  218.   /*
  219.    * Die Kommandozeile wird geparst. Falls ein Fehler
  220.    * beim Parsen auftrat, wird das Programm mit einer
  221.    * Fehlermeldung verlassen
  222.    */
  223.  
  224.   if ((argsptr = ReadArgs (TEMPLATE, opts, NULL)) == NULL)
  225.     {
  226.       ErrorHandle ("TemplateError", TASK_ERR, WRONG_FAIL, KILL);
  227.     }
  228.   else
  229.     {
  230.       /*
  231.        * Das Feld opts[] wird durchsucht, ob ein Flag
  232.        * gesetzt wurde. Falls eine gesetzte Option gefunden
  233.        * wurde, wird die Schleife abgebrochen und der
  234.        * entsprechende Rückgabewert gesetzt
  235.        */
  236.       for (j = 0; j < COUNT_FLAGS; j++)
  237.     if (opts[j])
  238.       {
  239.         ret = j;
  240.         break;
  241.       }
  242.  
  243.       /*
  244.        * Die Funktion ReadArgs() reserviert intern
  245.        * Speicherplatz für die Kommandoargumente.       Dieser
  246.        * Platz muß dem System mit der Prozedur FreeArgs()
  247.        * zurückgegeben werden
  248.        */
  249.       FreeArgs (argsptr);
  250.     }
  251.  
  252.   return (ret);
  253. }
  254.  
  255.  /*
  256.   * Die Prozedur HandleIDPort() wird aufgerufen, wenn RSys
  257.   * ein zweites Mal gestartet wird. Wird dabei ein Parameter
  258.   * übergeben, so wird dieser mit dem Message-System des
  259.   * AmigaDOS an den ID-Port des bereitsgestarteten Programms
  260.   * versendet und hier ausgewertet. Die Struktur RSYS_SysMsg
  261.   * enthält neben der Standard-System-Message noch die ID
  262.   * der anzuzeigenden Liste.
  263.   */
  264. static void
  265. HandleIDPort (void)
  266. {
  267.   RSYS_SysMsg *arrived_mess;
  268.   int ID;
  269.  
  270.   /*
  271.    * Es werden alle Nachrichten ausgewertet, solange, bis
  272.    * die Message-Queue leer ist.
  273.    */
  274.   while (arrived_mess = (RSYS_SysMsg *) GetMsg (SysIdPort))
  275.     {
  276.       ID = arrived_mess->sm_newtype;
  277.       ReplyMsg ((MESSAGE *) arrived_mess);
  278.  
  279.       /*
  280.          * Falls  das RSys-Hauptfenster mit dem Zip-Gadget auf
  281.          * eine kleine  Fenstergröße gebracht wurde, wird es
  282.          * jetzt  nach  vorne  geholt  und      auf normale Größe
  283.          * gebracht.
  284.        */
  285.       if (SysWnd->Flags & WFLG_ZOOMED)
  286.     {
  287.       WindowToFront (SysWnd);
  288.       ZipWindow (SysWnd);
  289.     }
  290.  
  291.       /*
  292.          * In jedem Fall wird das RSys-Hauptfenster aktiviert.
  293.        */
  294.       ActivateWindow (SysWnd);
  295.  
  296.       /*
  297.          * Ist die erhaltene Nachricht von einem zweiten
  298.          * RSys-Aufruf ohne Parameter abgesendet worden, steht
  299.          * das ID-Feld der RSYS_SysMsg-Struktur auf SYSTEMINFO.
  300.          * Falls ein Parameter angegeben wurde, wird die
  301.          * Anzeigeliste mit dem neuen Parameter aktualisiert
  302.          * und in der globalen Variablen LastID gemerkt.
  303.        */
  304.       if (ID != SYSTEMINFO)
  305.     RefreshList (LastID = ID);
  306.  
  307.       /*
  308.          * Während der ID-Port abgefragt wird, kann das
  309.          * Hauptfenster Nachrichten empfangen haben. Diese
  310.          * sollen nach dem Empfang der Nachricht vom zweiten
  311.          * Programmaufruf nicht ausgewertet werden. Deshalb
  312.          * werden jetzt die evtl. vorhandenen Nachrichten des
  313.          * Hauptfenster-Ports gelöscht.
  314.        */
  315.       ClearIntuiMsgPort (SysWnd);
  316.     }
  317.  
  318.   return;
  319. }
  320.  
  321. void
  322. SetMainLVTop (int top)
  323. {
  324.   GT_SetGadgetAttrs (SysGadgets[GD_ListeLV], SysWnd,
  325.              NULL,
  326.              GTLV_Top, top,
  327.              TAG_DONE);
  328.  
  329.   return;
  330. }
  331.  
  332.  /*
  333.   * Die Procedure HandleRawKeys() wertet die
  334.   * Tastatureingaben des Hauptfensters aus. Dazu wird
  335.   * das Feld IntuiMessage->Code verwendet.
  336.   */
  337. static void
  338. HandleRawKeys (ULONG code, ULONG qualifier)
  339. {
  340.   /*
  341.    * Es werden bei einem Tastatur-Event zwei Messages
  342.    * an den Hauptfenster-Port versendet, wenn die Taste
  343.    * gedrückt und dann, wenn sie losgelassen wurde.
  344.    * Hier sollen nur die Events ausgewertet werden, die
  345.    * direkt nach dem Drücken einer Taste anliegen.
  346.    */
  347.   if (code & IECODE_UP_PREFIX)
  348.     return;
  349.   if (qualifier & CTRLKEYS)
  350.     return;
  351.  
  352.   switch (code)
  353.     {
  354.       /*
  355.        * Falls die "Cursor-Down"-Taste gedrückt wurde, wird
  356.        * der oberste Eintrag des ListViews aktualisiert und
  357.        * auf den nächsten Eintrag gesetzt, falls es nicht
  358.        * schon der letzte oberste Eintrag war. Der globale
  359.        * Zähler topentry wird dann um eins erhöht.
  360.        */
  361.     case CURSORDOWN:
  362.       if (topentry < (countentries - newlvh))
  363.     {
  364.       topentry++;
  365.       SetMainLVTop (topentry);
  366.  
  367.       actualfindnode = GetNode (&ListeLVList, topentry);
  368.       actualfindnodenum = topentry;
  369.     }
  370.       break;
  371.  
  372.       /*
  373.        * Falls die "Cursor-Up"-Taste gedrückt wurde, wird
  374.        * der oberste Eintrag des ListViews aktualisiert und
  375.        * auf den vorherigen Eintrag gesetzt, falls es nicht
  376.        * schon der erste Eintrag der Liste war. Der globale
  377.        * Zähler topentry wird dann um eins erniedrigt.
  378.        */
  379.     case CURSORUP:
  380.       if (topentry > 0)
  381.     {
  382.       topentry--;
  383.       SetMainLVTop (topentry);
  384.  
  385.       actualfindnode = GetNode (&ListeLVList, topentry);
  386.       actualfindnodenum = topentry;
  387.     }
  388.       break;
  389.  
  390.       /*
  391.        * Das ListView zeigt den Anfang der Liste. Der
  392.        * Zähler topentry wird auf Null gesetzt.
  393.        */
  394.     case CURSORLEFT:
  395.       if (topentry != 0)
  396.     {
  397.       topentry = 0;
  398.       SetMainLVTop (topentry);
  399.  
  400.       actualfindnode = GetNode (&ListeLVList, topentry);
  401.       actualfindnodenum = topentry;
  402.     }
  403.       break;
  404.  
  405.       /*
  406.        * Das ListView zeigt das Ende der Liste. Der
  407.        * Zähler topentry wird auf den Eintrag mit der
  408.        * Nummer (Anzahl der Einträge - Anzahl der
  409.        * sichtbaren Einträge) gesetzt.
  410.        */
  411.     case CURSORRIGHT:
  412.       if (topentry != (countentries - newlvh))
  413.     {
  414.       topentry = (countentries - newlvh);
  415.       SetMainLVTop (topentry);
  416.  
  417.       actualfindnode = GetNode (&ListeLVList, topentry);
  418.       actualfindnodenum = topentry;
  419.     }
  420.       break;
  421.  
  422.     default:
  423. /*                      PrintStatistics(); */
  424.       break;
  425.     }
  426.  
  427.   return;
  428. }
  429.  
  430.  /*
  431.   * Die Funktion SelectGadget() simuliert den
  432.   * Gadget-Down-Klick eines Boolean-Gadgets.
  433.   */
  434. static void
  435. SelectGadget (GADGET * Gadget)
  436. {
  437.   UWORD oldpos;
  438.  
  439.   /*
  440.    * Dazu wird das Gadget aus der Gadget-Liste
  441.    * entfernt, das SELECTED-Flag gesetzt und das Gadget
  442.    * wieder an der gleichen Position in die Liste
  443.    * eingehängt.
  444.    */
  445.   oldpos = RemoveGadget (SysWnd, Gadget);
  446.   Gadget->Flags |= GFLG_SELECTED;
  447.   AddGadget (SysWnd, Gadget, (ULONG) oldpos);
  448.  
  449.   /*
  450.    * Nun wird das Gadget wieder aktualisiert und ein
  451.    * wenig gewartet.
  452.    */
  453.   RefreshGList (Gadget, SysWnd, NULL, 1);
  454.  
  455.   return;
  456. }
  457.  
  458.  /*
  459.   * Die Funktion UnSelectGadget() simuliert den
  460.   * Gadget-Up-Klick eines Boolean-Gadgets.
  461.   */
  462. static void
  463. UnSelectGadget (GADGET * Gadget)
  464. {
  465.   UWORD oldpos;
  466.  
  467.   /*
  468.    * Dazu wird das Gadget aus der Gadget-Liste
  469.    * entfernt, das SELECTED-Flag entfernt und das
  470.    * Gadget wieder an der gleichen Position in die
  471.    * Liste eingehängt.
  472.    */
  473.   oldpos = RemoveGadget (SysWnd, Gadget);
  474.   Gadget->Flags &= ~GFLG_SELECTED;
  475.   AddGadget (SysWnd, Gadget, (ULONG) oldpos);
  476.  
  477.   /*
  478.    * Nun wird das Gadget wieder aktualisiert.
  479.    */
  480.   RefreshGList (Gadget, SysWnd, NULL, 1);
  481.  
  482.   return;
  483. }
  484.  
  485.  /*
  486.   * Die Procedure HandleVanillaKeys() wertet die
  487.   * Tastatureingaben des Hauptfensters aus. Dazu wird
  488.   * das Feld IntuiMessage->Code verwendet.
  489.   */
  490. static void
  491. HandleVanillaKeys (ULONG code, ULONG qualifier)
  492. {
  493.   int ID;
  494.  
  495.   if (qualifier & CTRLKEYS)
  496.     return;
  497.  
  498.   /*
  499.    * Wurde die Esc-Taste gedrückt, werden zwei Fälle
  500.    * unterschieden. Wurde RSys von der WB gestartet,
  501.    * geht RSys in den AppIcon-Modus, wurde es von einem
  502.    * CLI gestartet, wird RSys beendet, indem das globale
  503.    * Flag Flags.quit_flag gesetzt wird.
  504.    */
  505.   if ((char) code == ESC && !Flags.wb_start)
  506.     {
  507.       Flags.quit_flag = 1;
  508.       return;
  509.     }
  510.  
  511.   /*
  512.    * Wurde RSys mit dem Zip-Gadget verkleinert, werden
  513.    * keine Vanillakeys ausgewertet.
  514.    */
  515.   if (SysWnd->Flags & WFLG_ZOOMED)
  516.     return;
  517.  
  518.   if ((char) ToUpper (code) == 'N')
  519.     {
  520.       SelectGadget (SysGadgets[GD_NewGad]);
  521.       RefreshList (LastID);
  522.       UnSelectGadget (SysGadgets[GD_NewGad]);
  523.       return;
  524.     }
  525.   /*
  526.    * Nun wird die Listen-ID aus dem Code des Gadgets
  527.    * ermittelt, dessen entsprechende Taste gedrückt
  528.    * wurde.
  529.    */
  530.   ID = position ((int) code);
  531.  
  532.   /*
  533.    * Entspricht die ID einer Gadget-ID, wird das
  534.    * entsprechende Gadget aktiviert und die
  535.    * entsprechende Aktion ausgeführt.  Dabei wird die
  536.    * ID des aktuellen ListView-Inhalts in LastID
  537.    * gemerkt.
  538.    */
  539.   if ((ID < GD_SaveListGad) && (ID != ~0))
  540.     {
  541.       HandleHelp ((enum RSysNumbers) ID);
  542.  
  543.       LastID = ID;
  544.  
  545.       SelectGadget (SysGadgets[LastID]);
  546.       RefreshList (ID);
  547.       UnSelectGadget (SysGadgets[LastID]);
  548.  
  549.       return;
  550.     }
  551.  
  552.   /*
  553.    * Wurde das Jump-Gadget aktiviert, schließt RSys sein
  554.    * Hauptfenster und öffnet es auf dem vordersten
  555.    * PublicScreen.
  556.    */
  557.   if (ID == GD_JumpGad)
  558.     {
  559.       Jump ();
  560.       return;
  561.     }
  562.  
  563.   /*
  564.    * Kommt das Programm bis hierhin, konnte der
  565.    * Tastenklick nicht erkannt werden. Es erfolgt eine
  566.    * entsprechende Nachricht im Message-Feld von RSys.
  567.    */
  568.   PrintStatistics ();
  569.  
  570.   return;
  571. }
  572.  
  573.  /*
  574.   * Die Prozedur HandleGadgets() verarbeitet die
  575.   * Gadgetevents. Zu einem Parameter gad wird die
  576.   * entsprechende Aktion ausgelöst.
  577.   */
  578. static void
  579. HandleGadgets (GADGET * gad)
  580. {
  581.   char fileout[MAXFULLNAME];
  582.   int ID = (int) gad->GadgetID;
  583.  
  584.   HandleHelp ((enum RSysNumbers) ID);
  585.  
  586.   if (ID == GD_NewGad)
  587.     {
  588.       RefreshList (LastID);
  589.       return;
  590.     }
  591.  
  592.   /*
  593.    * Falls die ListView-Liste abgespeichert werden
  594.    * soll, wird ein Asl-Requester angeboten und die
  595.    * Liste in eine ausgewählte Datei als Textdatei
  596.    * weggeschrieben.
  597.    */
  598.   if (ID == GD_SaveListGad)
  599.     {
  600.       sprintf (fileout, "RSys-%s.dat", EntryAttr[LastID].ea_type);
  601.  
  602.       if (GetFile (SysWnd, "RAM:", fileout, "#?.dat", "Select File for saving list", "Save"))
  603.     SaveList (SysWnd, (char *) _fullpath, EntryAttr[LastID].ea_type, &ListeLVList, TRUE);
  604.  
  605.       return;
  606.     }
  607.  
  608.   /*
  609.    * Handelt es sich um die anderen Gadgets, wird
  610.    * entsprechend der GadgetID das ListView
  611.    * aktualisiert.
  612.    */
  613.   if (ID < GD_SaveListGad)
  614.     {
  615.       LastID = ID;
  616.       RefreshList (ID);
  617.  
  618.       return;
  619.     }
  620.  
  621.   /*
  622.    * Wurde das Jump-Gadget aktiviert, schließt RSys sein
  623.    * Hauptfenster und öffnet es auf dem vordersten
  624.    * PublicScreen.
  625.    */
  626.   if (ID == GD_JumpGad)
  627.     Jump ();
  628.  
  629.   return;
  630. }
  631.  
  632.  /*
  633.   * Die Prozedur HandleMenu() verwaltet die
  634.   * Menu-Eingaben.
  635.   */
  636. static void
  637. HandleMenu (ULONG code)
  638. {
  639.   MENUITEM *item;
  640.   USHORT nextcode = (USHORT) code;
  641.   void (*fptr) (void);
  642.  
  643.   ReopenWindow = FALSE;
  644.  
  645.   DPOS;
  646.  
  647.   /*
  648.    * Falls ein Menüpunkt ausgewählt wurde, wird das
  649.    * entsprechende Menü-Item ermittelt. Aus dem
  650.    * UserData-Feld dieses Menüpunktes erhält man
  651.    * schließlich einen Zeiger auf die Funktion, die
  652.    * ausgeführt werden soll.
  653.    * Erweiterung: Werden mehrere Menüpunkte hintereinander
  654.    * angewählt, ohne das Menü zu desaktivieren, werden
  655.    * auch alle ausgewählt.
  656.    */
  657.   while (nextcode != MENUNULL && !ReopenWindow)
  658.     {
  659.       if ((item = ItemAddress (SysMenus, (long) nextcode)) != NULL)
  660.     {
  661.       /*
  662.        * Falls das UserData-Feld initialisiert wurde, wird
  663.        * der dort eingetragene Zeiger als Zeiger auf eine
  664.        * auszuführende Funktion genommen und ausgeführt.
  665.        */
  666.       if (fptr = (void (*)()) GTMENUITEM_USERDATA (item))
  667.         (*fptr) ();
  668.     }
  669.       else
  670.     break;
  671.  
  672.       nextcode = item->NextSelect;
  673.     }
  674.  
  675.   return;
  676. }
  677.  
  678.  /*
  679.   * HandleMainPort() bearbeitet die Nachrichten vom RSys-
  680.   * Hauptfenster und ruft die entsprechenden Unter-
  681.   * programme auf
  682.   */
  683. void
  684. HandleMainPort (void)
  685. {
  686.   INTUIMESSAGE *message;
  687.   ULONG class, code, qualifier;
  688.   APTR object;
  689.   static int refr = TRUE;
  690.   int GID;
  691.   static int oldh;
  692.  
  693.   while ((message = (INTUIMESSAGE *) GT_GetIMsg (SysWnd->UserPort)) != NULL)
  694.     {
  695.       /*
  696.        * Die wichtigsten Daten werden aus der erhaltenen
  697.        * Nachricht kopiert.
  698.        */
  699.       object = message->IAddress;
  700.       class = message->Class;
  701.       code = message->Code;
  702.       qualifier = message->Qualifier;
  703.  
  704.       /*
  705.        * Die Nachricht wird sofort beantwortet, damit
  706.        * Intuition nicht länger als notwendig auf eine
  707.        * Antwort wartet.
  708.        */
  709.       GT_ReplyIMsg (message);
  710.  
  711.       if (!Flags.helpmode && ICONIFY_REQUESTED)
  712.     {
  713.       Iconify ();
  714.       ClearIntuiMsgPort (SysWnd);
  715.  
  716.       return;
  717.     }
  718.  
  719.       /*
  720.        * Entsprechend der Art (der Klasse) der Nachricht
  721.        * werden die Aktionen ausgeführt.
  722.        */
  723.       switch (class)
  724.     {
  725.       /*
  726.        * Ist die Volumes-Liste im ListView aktiv und wurde
  727.        * ein Diskettenwechsel in den Laufwerken erkannt,
  728.        * wird die Liste automatisch aktualisiert.
  729.        */
  730.     case IDCMP_DISKINSERTED:
  731.     case IDCMP_DISKREMOVED:
  732.       if (LastID == VOLUMES)
  733.         RefreshList (LastID);
  734.  
  735.       break;
  736.  
  737.       /*
  738.        * Wurde eine Taste gedrückt, wird eine entsprechende
  739.        * Aktion gestartet. Falls ein Qualifier (also einer
  740.        * der Shift-, Amiga- und Control-Tasten oder eine
  741.        * Kombination von diesen) erkannt wurde, wird keine
  742.        * Aktion gestartet.
  743.        */
  744.     case IDCMP_VANILLAKEY:
  745.       HandleVanillaKeys (code, qualifier);
  746.       break;
  747.  
  748.       /*
  749.        * Wurde eine Taste oder Sondertaste gedrückt, wird
  750.        * eine entsprechende Aktion gestartet.  Falls ein
  751.        * Qualifier (also einer der Shift-, Amiga- und
  752.        * Control-Tasten oder eine Kombination von diesen)
  753.        * erkannt wurde, wird keine Aktion gestartet.
  754.        */
  755.     case RAWKEY:
  756.       HandleRawKeys (code, qualifier);
  757.       break;
  758.  
  759.       /*
  760.        * Wird ein Gadget auf dem Hauptfenster angeklickt,
  761.        * wird eine entsprechende Aktion gestartet.  Wurde
  762.        * das ListView angeklickt, wird versucht, den
  763.        * Eintrag zu modifizieren.
  764.        */
  765.     case IDCMP_GADGETUP:
  766.       GID = ((GADGET *) object)->GadgetID;
  767.  
  768.       if (GID == GD_ListeLV)
  769.         {
  770.           HandleHelp ((enum RSysNumbers) GID);
  771.           ModifyObject (LastID, code);
  772.         }
  773.       else
  774.         HandleGadgets ((GADGET *) object);
  775.       break;
  776.  
  777.       /*
  778.        * Wird das Hauptfenster gezipt, wird der Inhalt des
  779.        * Fensters und das Hintergrundmuster erneuert.
  780.        */
  781.     case IDCMP_CHANGEWINDOW:
  782.       if (NOT (SysWnd->Flags & WFLG_ZOOMED))
  783.         {
  784.           /*
  785.            * Das Fenster soll nur EINMAL refreshed werden.
  786.            * Diese IDCMP-Message kommt aber auch dann, wenn ein
  787.            * Fenster verschoben wurde, weshalb ein Flag extra
  788.            * eingeführt wurde.
  789.            */
  790.           if (NOT (refr))
  791.         {
  792.           RefreshMainWindowPattern ();
  793.  
  794.           refr = TRUE;
  795.  
  796.           if (Flags.autofront)
  797.             {
  798.               WindowToFront (SysWnd);
  799.               ActivateWindow (SysWnd);
  800.             }
  801.         }
  802.         }
  803.       else
  804.         refr = FALSE;
  805.       break;
  806.  
  807.     case IDCMP_SIZEVERIFY:
  808.       oldh = SysWnd->Height;
  809.       break;
  810.  
  811.     case IDCMP_NEWSIZE:
  812.       if ((SysWnd->Height - oldh) != 0)
  813.         ResizeWindowRefresh ();
  814.       break;
  815.  
  816.       /*
  817.        * Ein Menüpunkt wurde ausgewählt.
  818.        */
  819.     case MENUPICK:
  820.       HandleMenu (code);
  821.       break;
  822.  
  823.       /*
  824.        * Das Closegadget des Hauptfensters wurde geklickt.
  825.        * Nach einer Sicherheitsabfrage wird das Programm
  826.        * beendet.
  827.        */
  828.     case IDCMP_CLOSEWINDOW:
  829.       quit (TRUE);
  830.       break;
  831.  
  832.     default:
  833.       break;
  834.     }
  835.     }
  836.  
  837.   return;
  838. }
  839.  
  840.  /*
  841.   * Das Hauptprogramm. Hier werden alle
  842.   * Intuition-Events abgeholt und die entsprechenden
  843.   * Auswerteprozeduren aufgerufen.
  844.   */
  845. void
  846. main (int argc, char **argv)
  847. {
  848.   ULONG mask;
  849.  
  850.   DPOS;
  851.   /*
  852.    * Das Flag, daß die Beendung des Programms
  853.    * signalisiert wird initialisiert.
  854.    */
  855.   Flags.quit_flag = 0;
  856.  
  857.   InstallTrapHandlers ();
  858.  
  859.   /*
  860.    * Falls RSys vom CLI aus gestartet wurde, erscheint
  861.    * eine kleine Infozeile im CLI. Dann wird die
  862.    * globale Variable Flags.wb_start auf FALSE gesetzt, da
  863.    * das Programm in diesem Fall nicht von der WB aus
  864.    * gestartet wurde.
  865.    */
  866.   if (argc)
  867.     {
  868. /*
  869.    GMD
  870.    PutStr ((UBYTE *) & gmdv[7]);
  871.  */
  872.       Flags.wb_start = 0;
  873.     }
  874.   else
  875.     Flags.wb_start = 1;
  876.  
  877.   /*
  878.    * Falls bei einem CLI-Aufruf Parameter mit angegeben
  879.    * wurden, werden diese ausgewertet.
  880.    */
  881.   if (argc >= 2)
  882.     LastID = HandleArguments (argv);
  883.  
  884.   /*
  885.    * Es wird festgestellt, ob das Programm bereits
  886.    * gestartet wurde. Wurde es bereits gestartet, wird
  887.    * das Programm beendet. Dabei werden die evtl.
  888.    * angegebenen und verarbeiteten Parameter an das
  889.    * bereits laufende Programm verschickt.
  890.    */
  891.   if (SysStarted (LastID))
  892.     CloseAll ();
  893.  
  894.   /*
  895.    * Alle notwendigen Ressourcen (Libraries, RSys-Ports
  896.    * etc.) werden eröffnet und bereitgestellt.
  897.    */
  898.   OpenLibs ();
  899.  
  900.   /*
  901.    * Der ID-Port wird erzeugt. An der Existenz dieses
  902.    * Ports kann bei einem zweiten Aufruf des Programms
  903.    * festgestellt werden, ob RSys bereits gestartet
  904.    * wurde.
  905.    */
  906.   if (!(SysIdPort = CreatePort (ID_PORT_NAME, 0)))
  907.     ErrorHandle ((char *) ID_PORT_NAME, PORT_ERR, CREATE_FAIL, KILL);
  908.  
  909.   /*
  910.    * Das ListView wird initialisiert.
  911.    */
  912.   NewList (&ListeLVList);
  913.  
  914.   /*
  915.    * Falls der Aufruf von der WB aus geschah, wird RSys
  916.    * "iconifiziert", d.h. ein AppIcon wird auf der
  917.    * WB erzeugt. Andernfalls wird das Hauptfenster
  918.    * geöffnet und entsprechend der Nummer LastID das
  919.    * ListView aktualisiert.
  920.    */
  921.   if (Flags.wb_start)
  922.     Iconify ();
  923.   else
  924.     {
  925.       OpenMainWindow ();
  926.       RefreshList (LastID);
  927.     }
  928.  
  929.   /*
  930.    * Schleifenbeginn. Solange, bis ein
  931.    * Abbruchkriterium erkannt wurde (Flags.quit_flag ist
  932.    * TRUE), wird auf das Setzen der entsprechenden
  933.    * Flags gewartet.
  934.    */
  935.   do
  936.     {
  937.       /*
  938.        * Warten auf folgende Events:
  939.        * - ^C wurde eingegeben
  940.        * - Events vom Hauptfenster
  941.        * - Events vom ID-Port
  942.        * - Events vom Broker-Port.
  943.        */
  944.       mask = Wait (SIGBREAKF_CTRL_C |
  945.            (1L << SysWnd->UserPort->mp_SigBit) |
  946.            (1L << SysIdPort->mp_SigBit) |
  947.            (1L << broker_mp->mp_SigBit));
  948.  
  949.       /*
  950.        * Falls ein ^C eingegeben wurde, wird das
  951.        * Programmbeendigungsflag gesetzt.
  952.        */
  953.       if (CTRL_C_RECEIVED)
  954.     Flags.quit_flag = 1;
  955.  
  956.       /*
  957.        * Wenn das Programm ein zweitesmal aufgerufen wird,
  958.        * erhält der ID-Port eine Nachricht.
  959.        */
  960.       if (ID_PORT_SIG_RECEIVED)
  961.     HandleIDPort ();
  962.  
  963.       /*
  964.        * Falls von dem System-Programm Exchange ein Signal
  965.        * gesendet wurde, wird es hier verarbeitet.
  966.        */
  967.       if (BROKER_PORT_SIG_RECEIVED)
  968.     HandleBrokerPort ();
  969.  
  970.       /*
  971.        * Falls das Hauptfenster ein Signal erhalten hat,
  972.        * werden die Daten der Nachricht(en) gemerkt und
  973.        * weiterverarbeitet.
  974.        */
  975.       if (WINDOW_PORT_SIG_RECEIVED)
  976.     HandleMainPort ();
  977.     }
  978.   /*
  979.    * Das Programm läuft solange, bis das Flags.quit_flag
  980.    * gesetzt wurde.
  981.    */
  982.   while (NOT ((Flags.quit_flag)));
  983.  
  984.   /*
  985.    * Die geöffneten Resourcen werden geschlossen und
  986.    * das Programm beendet.
  987.    */
  988.   CloseAll ();
  989.  
  990.   return;
  991. }
  992.